#!/usr/bin/env bash

# This should be copied to .git/hooks/pre-commit

function go_imports() {
    if ! type goimports &> /dev/null; then
        echo "Installing goimports"
        go install golang.org/x/tools/cmd/goimports
    fi

    # Formats each file that was changed.
    for file in $(git diff --cached --name-only --diff-filter=ACM | grep '\.go$')
    do
        goimports -w "${file}"
        git add "$file"
    done

}

function generate_crd(){
  echo "Generating CRD"
  make manifests
  git add config/crd/bases/mongodbcommunity.mongodb.com_mongodbcommunity.yaml
}

function mypy_check()
{
    local exit_status=0
    # Mypy doesn't support recursive traversal of directories
    # So we manually call it on every staged python file
    echo "Running mypy on staged python files"
    for file in $(git diff --cached --name-only --diff-filter=ACM | grep '\.py$')
    do
        echo "Analyzing $file ..."
        # We ignore missing import otherwise mypy will complain
        # about 3rd party libraries not providing type hints
        if ! mypy --disallow-untyped-calls --disallow-untyped-defs --disallow-incomplete-defs --ignore-missing-imports "${file}"; then
            exit_status=1
        fi
    done
    return $exit_status
}

function go_linting() {
    dirs_to_analyze=()
    for file in $(git diff --cached --name-only --diff-filter=ACM | grep '\.go$')
    do
        dirs_to_analyze+=("$(dirname "${file}")" )
    done
    if [ ${#dirs_to_analyze[@]} -ne 0 ]; then
        mapfile -t dirs_to_analyze < <(printf '%s\n' "${dirs_to_analyze[@]}" | sort -u)
        echo "Running golangci-lint on staged files"
        local exit_status=0
        for file in "${dirs_to_analyze[@]}"
        do
            if ! golangci-lint run "${file}"; then
                exit_status=1
            fi
        done
        return $exit_status
    fi

    return 0
}

function black_formatting()
{
    # Black formatting of every python file that was changed
    for file in $(git diff --cached --name-only --diff-filter=ACM | grep '\.py$')
    do
        black -q "$file"
        git add "$file"
    done
}

function generate_github_actions(){
  scripts/dev/generate_github_actions.py
  git add .github/workflows
}

generate_github_actions
generate_crd
go_imports
black_formatting
if ! mypy_check; then
    echo "MyPy returned some errors, please correct them"
    echo "Commit aborted"
    # In some cases we might encounter mypy errors that we do not
    # actually treat as such. So we provide a link to the dev
    # for ignoring them through code annotation
    echo "If some of the errors reported are false positives "\
         "and should be ignored, mypy provides a way to silence "\
         "errors: https://mypy.readthedocs.io/en/stable/common_issues.html#spurious-errors-and-locally-silencing-the-checker"
    echo "Please use this only for errors that you are sure are"\
         "false positives."
    exit 1
fi
if ! go_linting; then
    echo "Golancli-lint returned some errors, please correct them"
    echo "Commit aborted"
    # In some cases we might encounter mypy errors that we do not
    # actually treat as such. So we provide a link to the dev
    # for ignoring them through code annotation
    echo "If some of the errors reported are false positives "\
         "and should be ignored, golanci-lint  provides a way to silence "\
         "errors: https://golangci-lint.run/usage/false-positives/"
    echo "Please use this only for errors that you are sure are"\
         "false positives."
    exit 1
fi
